package org.sidora.core;

import java.text.NumberFormat;
import java.util.Arrays;
import java.util.List;

import com.db4o.ObjectContainer;
import com.db4o.ObjectSet;
import com.db4o.query.Predicate;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.logging.Level;
import org.sidora.core.util.AbstractFactory;
import org.sidora.core.util.AbstractInventory;
import org.sidora.core.util.LoggerProvider;
import org.sidora.core.util.OCProvider;
import org.sidora.core.util.ParameterCollector;



/**
 * Phase
 * @author Enric Tartera, Juan Manuel Gimeno, Roger Masgoret
 * @version 1.0
 */
public class Phase implements Comparable{
    private String id;
    private String name;
    private Dating dating;
    private Site site;
    
    private Phase(){}
    
    
    
    @Override
    public boolean equals(Object obj) {
        if (obj == this)	return true;
        if (!(obj instanceof Phase)) return false;
        Phase phase = null;
        try {
            phase = (Phase) obj;
        } catch (Exception e) {
            return false;
        }
        if (this.id != phase.id) return false;
        return true;
    }
    
    @Override
    public String toString() {
        String text= name+" ("+dating.getTpq().toString()+"/"+dating.getTaq().toString()+") "+id;
        return text;
    }
    
    

    public static class Inventory extends AbstractInventory{
        
        public boolean exist(final String id) throws Exception{
            
            ObjectContainer db = OCProvider.getInstance();
            ObjectSet<Phase> phases = db.query(new Predicate<Phase>() {
                
                
                public boolean match(Phase candidate) {
                    return candidate.id.equals(id);
                }
            });
            
            if (phases.hasNext()){
                return true;
            } else {
                return false;
            }
        }
        
        public Phase getNewObject(ParameterCollector param) throws Exception{
            
            String newId= (String) param.get("id");
            
            if (!exist(newId)){
                LoggerProvider.getInstance().info("New Phase created");
                return new Phase();
            }else {
                LoggerProvider.getInstance().info("Existing Phase returned: "+newId);
                return (Phase) getObject(param);
            }
            
        }
        
        public static String getNewKey() {
            ObjectContainer db = OCProvider.getInstance();
            ObjectSet <Phase> phases = db.query(Phase.class);
            SortedSet <Integer>sorted = new TreeSet<Integer>();
            
            NumberFormat form = NumberFormat.getInstance();
            form.setMinimumIntegerDigits(3);
            
            if (phases.size()!=0){
                while (phases.hasNext()){
                    Phase aPhase = phases.next();
                    try{
                        Integer integer = Integer.parseInt(aPhase.getId());
                        sorted.add(integer);
                    }catch (NumberFormatException e){
                        LoggerProvider.getInstance().log(Level.WARNING,"Not an integer",e);
                    }
                }
                int last = sorted.last().intValue();
                return form.format(last+1);
            } else return "001";
            
            
        }
        
        public KeyObject getNewKey(ParameterCollector param)  {
            return null;
            
        }
        
        
        public Object getObject(ParameterCollector param) {
            //Carrega el Site amb el corresponent siteid
            final String key = (String) param.get("id");
            ObjectContainer db = OCProvider.getInstance();
            
            ObjectSet <Phase> phases = db.query(new Predicate <Phase>() {
                public boolean match(Phase aphase) {
                    return (aphase.getId().equals(key));
                }
            });
            
            
            if (phases.hasNext()){
                return phases.next();
            } else throw new RuntimeException("Fase inexistent");
        }
        
        public static List getList() {
            
            ObjectContainer db = OCProvider.getInstance();
            List<Phase> list = db.query(Phase.class);
            
            return list;
            
        }
        
        public static List getList(final Site site) {
            ObjectContainer db = OCProvider.getInstance();
            List<Phase> list = db.query(new Predicate<Phase>(){
                
                @Override
                public boolean match(Phase phase) {
                    // TODO Auto-generated method stub
                    return phase.site==site;
                }});
                
                return list;
        }
    }
    
    public int compareTo(Object obj) {
        return this.toString().compareTo(obj.toString());
    }
    
    public String getId() {
        return id;
    }
    
    public void setId(String id) {
        this.id = id;
    }
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public Dating getDating() {
        return dating;
    }
    public void setDating(Dating dating) {
        this.dating = dating;
    }
    
    public Site getSite() {
        return site;
    }
    public void setSite(Site site) {
        this.site = site;
    }
} // end Fase



